package com.atguigu.tingshu.album.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.file.FileNameUtil;
import cn.hutool.core.util.IdUtil;
import com.atguigu.tingshu.album.config.MinioConstantProperties;
import com.atguigu.tingshu.album.service.AuditService;
import com.atguigu.tingshu.album.service.FileUploadService;
import com.atguigu.tingshu.common.execption.GuiguException;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import io.minio.errors.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

/**
 * @author 饭勺
 * @description
 * @createDate 2025/9/22 17:16
 */
@Service
public class FileUploadServiceImpl implements FileUploadService {

    @Autowired
    private MinioClient minioClient;

    @Autowired
    private MinioConstantProperties minioConstantProperties;

    @Autowired
    private AuditService auditService;

    /**
     * 图片（封面、头像）文件上传
     * 前端提交文件参数名：file
     *
     * @param multipartFile
     * @return
     */
    @Override
    public String fileUpload(MultipartFile multipartFile) throws IOException, ServerException, InsufficientDataException, ErrorResponseException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        //1.业务校验验证图片内容格式是否合法
            BufferedImage bufferedImage = ImageIO.read(multipartFile.getInputStream());
            if (bufferedImage == null) {
                throw new GuiguException(500, "上传文件类型错误！请上传图片！");
            }
            //2.业务校验-验证图片大小合法
            int width = bufferedImage.getWidth();
            int height = bufferedImage.getHeight();
            if (width > 900 || height > 900) {
                throw new GuiguException(500, "上传图片大小超限！请上传900*900的图片！");
            }
            //3.验证图片是否合法
            String suggestion = auditService.auditImage(multipartFile);
            if ("block".equals(suggestion) || "review".equals(suggestion)) {
                throw new GuiguException(500, "图片违规！请重新上传!");
            }

                //4.将文件上传到MInIO
                //4.1 生成带有文件夹目录文件名称 形式：/日期/随机文件名称.后缀
                String folder = "/" + DateUtil.today();
                String fileName = IdUtil.randomUUID();
                String extName = FileNameUtil.extName(multipartFile.getOriginalFilename());
                String objName = folder + "/" + fileName + "." + extName;
                //4.2 调用minio客户对象上传文件方法
                String bucketName = minioConstantProperties.getBucketName();
                minioClient.putObject(
                        PutObjectArgs.builder().bucket(bucketName).object(objName).stream(
                                        multipartFile.getInputStream(), multipartFile.getSize(), -1)
                                .contentType(multipartFile.getContentType())
                                .build());

                //5 拼接上传文件在线路径地址/返回图片访问路径
                return minioConstantProperties.getEndpointUrl() + "/" + bucketName + objName;
        }
    }
